return -1;
}
- /* The normal live-migration QEMU record has no length information.
+ /* The legacy live-migration QEMU record has no length information.
* Short of reimplementing the QEMU parser, we're forced to just read
- * until EOF. Remus gets around this by sending a different signature
- * which includes a length prefix */
+ * until EOF.
+ *
+ * Gets around this by sending a different signatures for the new
+ * live-migration QEMU record and Remus which includes a length
+ * prefix
+ */
if ( !memcmp(qemusig, "QemuDeviceModelRecord", sizeof(qemusig)) )
return compat_buffer_qemu(xch, ctx, fd, buf);
- else if ( !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) )
+ else if ( !memcmp(qemusig, "DeviceModelRecord0002", sizeof(qemusig)) ||
+ !memcmp(qemusig, "RemusDeviceModelState", sizeof(qemusig)) )
return buffer_qemu(xch, ctx, fd, buf);
qemusig[20] = '\0';
int debug = info != NULL && info->flags & XL_SUSPEND_DEBUG;
int rc = 0;
- libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug);
- if (hvm)
+ rc = libxl__domain_suspend_common(ctx, domid, fd, hvm, live, debug);
+ if (!rc && hvm)
rc = libxl__domain_save_device_model(ctx, domid, fd);
return rc;
}
callbacks.switch_qemu_logdirty = libxl__domain_suspend_common_switch_qemu_logdirty;
callbacks.data = &si;
- xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm);
+ rc = xc_domain_save(ctx->xch, fd, domid, 0, 0, flags, &callbacks, hvm);
+ if ( rc ) {
+ LIBXL__LOG_ERRNO(ctx, LIBXL__LOG_ERROR, "saving domain");
+ rc = ERROR_FAIL;
+ }
if (si.suspend_eventchn > 0)
xc_suspend_evtchn_release(ctx->xch, si.xce, domid, si.suspend_eventchn);
if (si.xce > 0)
xc_evtchn_close(si.xce);
- rc = 0;
out:
libxl__free_all(&gc);
return rc;
int fd2, c;
char buf[1024];
char *filename = libxl__sprintf(&gc, "/var/lib/xen/qemu-save.%d", domid);
+ struct stat st;
+ uint32_t qemu_state_len;
LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Saving device model state to %s", filename);
libxl__xs_write(&gc, XBT_NULL, libxl__sprintf(&gc, "/local/domain/0/device-model/%d/command", domid), "save");
libxl__wait_for_device_model(ctx, domid, "paused", NULL, NULL);
+ if (stat(filename, &st) < 0)
+ {
+ LIBXL__LOG(ctx, LIBXL__LOG_ERROR, "Unable to stat qemu save file\n");
+ return ERROR_FAIL;
+ }
+
+ qemu_state_len = st.st_size;
+ LIBXL__LOG(ctx, LIBXL__LOG_DEBUG, "Qemu state is %d bytes\n", qemu_state_len);
+
c = libxl_write_exactly(ctx, fd, QEMU_SIGNATURE, strlen(QEMU_SIGNATURE),
"saved-state file", "qemu signature");
if (c)
return c;
+
+ c = libxl_write_exactly(ctx, fd, &qemu_state_len, sizeof(qemu_state_len),
+ "saved-state file", "saved-state length");
+ if (c)
+ return c;
+
fd2 = open(filename, O_RDONLY);
while ((c = read(fd2, buf, sizeof(buf))) != 0) {
if (c < 0) {